home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / xulrunner / python / config.py < prev    next >
Encoding:
Python Source  |  2007-11-12  |  4.7 KB  |  143 lines

  1. # Miro - an RSS based video player application
  2. # Copyright (C) 2005-2007 Participatory Culture Foundation
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  17.  
  18. from threading import RLock
  19. import os
  20. import traceback
  21.  
  22. import util
  23. import prefs
  24. import resources
  25. import eventloop
  26. import platformcfg
  27. import urllib
  28. import logging
  29.  
  30. __appConfig = None
  31. __themeConfig = dict()
  32. __data = None
  33. __lock = RLock()
  34. __callbacks = set()
  35.  
  36. def addChangeCallback(callback):
  37.     __callbacks.add(callback)
  38.  
  39. def removeChangeCallback(callback):
  40.     __callbacks.discard(callback)
  41.  
  42. # The theme parameter is a horrible hack to load the theme before we
  43. # can import other modules. pybridge makes the extra, early call
  44. def load(theme = None):
  45.     global __appConfig
  46.     global __themeConfig
  47.     global __data
  48.     __lock.acquire()
  49.     try:
  50.         if __appConfig is None and __data is None:
  51.             # There's some sleight-of-hand here. The Windows port needs to
  52.             # look up config.LONG_APP_NAME and config.PUBLISHER to compute
  53.             # the path to the data file that is read when load() is
  54.             # called. Setting __appConfig to a true value (and populating
  55.             # it with those keys) before calling load() ensures that (a)
  56.             # the values will be available and (b) we won't get caught in
  57.             # an infinite loop of load()s. But in general, you shouldn't
  58.             # call config.get() or config.set() from platformcfg.load()
  59.             # unless you know exactly what you are doing, and maybe not
  60.             # even then.
  61.             __appConfig = util.readSimpleConfigFile(resources.path('app.config'))
  62.  
  63.             # Load the preferences
  64.             __data = platformcfg.load()
  65.             if __data is None:
  66.                 __data = dict()
  67.  
  68.             # This is a bit of a hack to automagically get the serial
  69.             # number for this platform
  70.             prefs.APP_SERIAL.key = ('appSerial-%s' % get(prefs.APP_PLATFORM))
  71.         if theme is not None:
  72.             logging.info("Using theme %s" % theme)
  73.             try:
  74.                 __themeConfig = util.readSimpleConfigFile(os.path.join(
  75.                     get(prefs.THEME_DIRECTORY),
  76.                     theme,
  77.                     'app.config'))
  78.             except:
  79.                 logging.warn("Failed to load theme %s" % theme)
  80.                 
  81.     finally:
  82.         __lock.release()
  83.  
  84. def save():
  85.     __lock.acquire()
  86.     try:
  87.         __checkValidity()
  88.         platformcfg.save( __data )
  89.     finally:
  90.         __lock.release()
  91.  
  92. def get(descriptor):
  93.     __lock.acquire()
  94.     try:
  95.         __checkValidity()
  96.  
  97.         if __data is not None and descriptor.key in __data:
  98.             return __data[descriptor.key]
  99.         elif descriptor.platformSpecific:
  100.             return platformcfg.get(descriptor)
  101.         elif descriptor.key in __themeConfig:
  102.             return __themeConfig[descriptor.key]
  103.         elif descriptor.key in __appConfig:
  104.             return __appConfig[descriptor.key]
  105.         else:
  106.             return descriptor.default
  107.     finally:
  108.         __lock.release()
  109.  
  110. def getList(descriptor):
  111.     return [urllib.unquote(i) for i in get(descriptor).split(",") if i]
  112.  
  113. def getAppConfig():
  114.     __lock.acquire()
  115.     try:
  116.         __checkValidity()
  117.         return __appConfig.copy()
  118.     finally:
  119.         __lock.release()
  120.     
  121. def set(descriptor, value):
  122.     __lock.acquire()
  123.     logging.debug("Setting %s to %s", descriptor.key, value)
  124.     try:
  125.         __checkValidity()
  126.         if descriptor.key not in __data or __data[ descriptor.key ] != value:
  127.             __data[ descriptor.key ] = value
  128.             __notifyListeners(descriptor.key, value)
  129.     finally:
  130.         __lock.release()
  131.  
  132. def setList(descriptor, value):
  133.     set(descriptor, ','.join ([urllib.quote(i) for i in value]))
  134.  
  135. def __checkValidity():
  136.     if __appConfig == None:
  137.         load()
  138.  
  139. def __notifyListeners(key, value):
  140.     for callback in __callbacks:
  141.         eventloop.addIdle(callback, 'config callback: %s' % callback,
  142.                 args=(key,value))
  143.